'''
Created on 17/09/2013

@author: daniel
'''
import unittest
import colecciones.nodoBinario 

class ArbolBinario(object):
    '''
    clase arbol binario: asociada a la clase NodoBinario
    '''
    
    def __init__(self,unObjeto):
        self.nodo=colecciones.nodoBinario.NodoBinario(unObjeto)
        
    def add(self,unArbolBinario):
        '''
        agrega unArbolBinario conteniendo en la raiz un objeto que implementa __cmp__
        '''
        if(self.nodo.__cmp__(unArbolBinario.nodo)==0):return None
        elif (self.nodo.__cmp__(unArbolBinario.nodo)<0):
            if(self.getR()==None):
                unArbolBinario.nodo.setNivel(self.nodo.getNivel()+1) 
                self.nodo.setLinkR(unArbolBinario)
                return self #devuelve el padre del incertado
            return self.getR().add(unArbolBinario)
        else:
            if(self.getL()==None):
                unArbolBinario.nodo.setNivel(self.nodo.getNivel()+1) 
                self.nodo.setLinkL(unArbolBinario)
                return self #devuelve el padre del incertado
            return self.getL().add(unArbolBinario)
            
    
    def delL(self):
        nodo=self.nodo.getLinkL()
        self.nodo.setLinkL(None)
        return nodo
    
    def delR(self):
        nodo=self.nodo.getLinkR()
        self.nodo.setLinkR(None)
        return nodo
    
    def getObjeto(self):
        return self.nodo.getObjeto()
    
    def getL(self):
        return self.nodo.getLinkL()
    
    def getR(self):
        return self.nodo.getLinkR()
         

class Test(unittest.TestCase):

    def testInit(self):
        obj=ArbolBinario(500)
        self.assertIsInstance(obj, ArbolBinario, "verifica correcta creacion")
        self.assertEquals(obj.nodo.getNivel(),0, "verifica correcto nivel de raiz")
        
    def testGetObjeto(self):
        obj=ArbolBinario(8)
        self.assertEquals(obj.getObjeto(), 8, "Verifica devolucion de objeto")
        
    def testAdd(self):
        obj=ArbolBinario(1)
        obj.add(ArbolBinario(2))
        self.assertIsNone(obj.getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getObjeto(), 2, "se verifica que agrega elemento")
        self.assertEquals(obj.getR().nodo.getNivel(), 1, "Verifica aumento de nivel")
        obj.add(ArbolBinario(10))
        self.assertIsNone(obj.getR().getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getR().getObjeto(), 10, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().nodo.getNivel(), 2, "Verifica aumento de nivel")
        obj.add(ArbolBinario(7))
        self.assertIsNotNone(obj.getR().getR().getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getR().getL().getObjeto(), 7, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().nodo.getNivel(), 3, "Verifica aumento de nivel")
        obj.add(ArbolBinario(8))
        self.assertIsNotNone(obj.getR().getR().getL().getR(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getR().getL().getR().getObjeto(), 8, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getR().nodo.getNivel(), 4, "Verifica aumento de nivel")
        
    def testDelL(self):
        obj=ArbolBinario(1)
        obj.add(ArbolBinario(2))
        self.assertIsNone(obj.getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getObjeto(), 2, "se verifica que agrega elemento")
        self.assertEquals(obj.getR().nodo.getNivel(), 1, "Verifica aumento de nivel")
        obj.add(ArbolBinario(10))
        self.assertIsNone(obj.getR().getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getR().getObjeto(), 10, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().nodo.getNivel(), 2, "Verifica aumento de nivel")
        obj.add(ArbolBinario(7))
        self.assertIsNotNone(obj.getR().getR().getL(),"verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getObjeto(), 7, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().nodo.getNivel(), 3, "Verifica aumento de nivel")
        obj.add(ArbolBinario(8))
        self.assertIsNotNone(obj.getR().getR().getL().getR(),"verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getR().getObjeto(), 8, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getR().nodo.getNivel(), 4, "Verifica aumento de nivel")
        obj.getR().getR().delL()
        self.assertIsNone(obj.delR().getR().getL(), "Verifica rama borrada")
        
    def testDelR(self):
        obj=ArbolBinario(1)
        obj.add(ArbolBinario(2))
        self.assertIsNone(obj.getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getObjeto(), 2, "se verifica que agrega elemento")
        self.assertEquals(obj.getR().nodo.getNivel(), 1, "Verifica aumento de nivel")
        obj.add(ArbolBinario(10))
        self.assertIsNone(obj.getR().getL(),"verifica correcta no insercion")
        self.assertEquals(obj.getR().getR().getObjeto(), 10, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().nodo.getNivel(), 2, "Verifica aumento de nivel")
        obj.add(ArbolBinario(7))
        self.assertIsNotNone(obj.getR().getR().getL(),"verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getObjeto(), 7, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().nodo.getNivel(), 3, "Verifica aumento de nivel")
        obj.add(ArbolBinario(8))
        self.assertIsNotNone(obj.getR().getR().getL().getR(),"verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getR().getObjeto(), 8, "verifica correcta insercion")
        self.assertEquals(obj.getR().getR().getL().getR().nodo.getNivel(), 4, "Verifica aumento de nivel")
        obj.getR().getR().delR()
        self.assertIsNone(obj.delR().getR().getR(), "Verifica rama borrada")
        
        
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()